home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / asm_subr.arc / FPIN < prev    next >
Encoding:
Text File  |  1985-12-25  |  5.6 KB  |  236 lines

  1. ;-------------------------fpin begins--------------------------+
  2. ; from BLUEBOOK OF ASSEMBLY ROUTINES FOR IBM PC & XT.
  3. ;         page : 88
  4. ;
  5. ; NAME FPIN
  6. ;
  7. ; ROUTINE FOR CONVERSION FROM EXTERNAL TO INTERNAL FLOATING POINT
  8. ;
  9. ; FUNCTION: This routine accepts an ASCII decimal floating point number
  10. ; from a std input device and converts it to internal binary floating
  11. ; point.
  12. ;
  13. ; INPUT: The characters of the floating point number are received in ASCII
  14. ; through a call to a std input routine.  The decimal floating point number
  15. ; has an optional sign, followed by decimal digits of the mantissa with one
  16. ; embedded decimal point.  Following the mantissa is an optional exponent
  17. ; which starts with the letter 'E', then an optional sign, then a decimal
  18. ; number.  It is possible to get erroneous results if the number is too
  19. ; large or small to be stored as a single precision binary floating point
  20. ; number.
  21. ;
  22. ; OUTPUT: Upon exit a single precision binary floating point number is in
  23. ; SFPBUFF.  The single precision floating point number has a 24-bit binary
  24. ; mantissa, a sign bit, and an 8-bit exponent biased by 128.
  25. ;
  26. ; REGISTERS USED:  No registers are modified.
  27. ;
  28. ; SEGMENTS REFERENCED:  The data segment contains the variables FPTEMP1,
  29. ; FPTEMP2, and SFPBUFF.
  30. ;
  31. ; ROUTINES CALLED:  STDIN, FPINDIGT, FPTMUL, FPTDIV and FPTNORM
  32. ;
  33. ; SPECIAL NOTES: Equates are used to shorten address fields.
  34. ;
  35. ; ROUTINE TO CONVERT FROM ASCII EXTERNAL TO INTERNAL FLOATING POINT
  36. ;
  37. fpin    proc    far
  38. ;
  39.     push    di        ; save registers
  40.     push    si
  41.     push    dx
  42.     push    cx
  43.     push    ax
  44. ;
  45. ; clear fp temp1 buffer
  46.     lea    di,fptemp1    ; point to fptemp1
  47.     mov    al,0        ; digit = 0
  48.     call    fpindigt    ; store digit
  49. ;
  50. ; clear the decimal flap and the count
  51.     mov    decflag,0    ; clear the flag
  52.     mov    decexp,0    ; clear the decimal exponent
  53. ;
  54. ; look for the sign
  55.     call     stdin        ; look for sign
  56.     cmp    al,'-'        ; minus ?
  57.     jz    fpin1        ; store it
  58.     cmp    al,'+'        ; plus ?
  59.     jz    fpin2        ; ignore it
  60.     jmp    fpin3        ; anything else is a player
  61. ;
  62. fpin1:
  63. ; set sign as a negative
  64.     mov    fptemp1b10,80h    ; put sign in place
  65. ;
  66. fpin2:
  67.     call    stdin        ; get next digit
  68. ;
  69. fpin3:
  70.     cmp    al,'.'        ; check for decimal point
  71.     jne    fpin4        ; press on if not
  72. ;
  73. ; set decimal flag
  74.     cmp    decflag,0    ; decimal flag already set ?
  75.     jne    fpin5        ; exit if not the first
  76.     mov    decflag,0FFh    ; set it now.
  77.     jmp    fpin2        ; go back for a digit
  78. ;
  79. fpin4:
  80.     sub    al,30h        ; bring down from ASCII
  81.     jl    fpin5        ; too low ?
  82.     cmp    al,9
  83.     jg    fpin5        ; too high ?
  84.     jmp    fpin6        ; got a digit
  85. ;
  86. fpin5:
  87.     jmp    fpin15        ; end of mantissa
  88. ;
  89. ; load digit as a floating point number
  90. fpin6:
  91.     lea    di,fptemp2    ; point to fptemp2
  92.     call    fpindigt    ; put in the digit
  93. ;
  94. ; multiply result by 10
  95.     lea    di,fptemp1    ; point to fptemp1
  96.     call    fptmul        ; multiply by 10
  97. ;
  98. ; pick one with a larger exponent
  99.     mov    cx,fptemp1w11    ; get sign of fptemp1
  100.     sub    cx,fptemp2w11    ; subtract sign of fptemp2
  101.     je    fpin11        ; skip if equal
  102.     jg    fpin9        ; if exponent fptemp2 is less
  103. ;
  104. fpin7:
  105. ; shift the bits
  106.     sar    fptemp1w8,1    ; shift all bits right
  107.     rcr    fptemp1w6,1    ; carry on
  108.     rcr    fptemp1w4,1
  109.     rcr    fptemp1w2,1
  110.     rcr    fptemp1w0,1
  111.     loop    fpin8
  112. ;
  113. ; set the exponent
  114.     mov    ax,fptemp2w11    ; get exponent of fptemp2
  115.     mov    fptemp1w11,ax    ; put in exponent of fptemp1
  116. ;
  117.     jmp    fpin11        ; done withthis case
  118. ;
  119. fpin9:
  120. ;
  121. ; exponent of fptemp2 is less than exp of fptemp1
  122. ;
  123. fpin10:
  124. ; shift the bits
  125.     sar    fptemp2w8,1    ; shift all bits right
  126.     rcr    fptemp2w6,1    ; carry on
  127.     rcr    fptemp2w4,1
  128.     rcr    fptemp2w2,1
  129.     rcr    fptemp2w0,1
  130.     loop    fpin10
  131. ;
  132. ; set the exponent
  133.     mov    ax,fptemp1w11    ; get exp of fptemp1
  134.     mov    fptemp2w11,ax    ; put in exp of fptemp2
  135.     jmp    fpin11        ; end of this case
  136. ;
  137. fpin11:
  138. ;
  139. ; add the digit to result
  140. ;
  141.     mov    cx,5        ; for a count of 5 words
  142.     lea    di,fptemp1    ; di points to fptemp1
  143.     lea    si,fptemp2    ; si points to fptemp2
  144.     clc
  145. ;
  146. fpin12:
  147.     mov    ax,[si]        ; get 16-bit digit from fptemp1
  148.     inc    si        ; point to next 16-bit digit
  149.     inc    si
  150.     adc    [di],ax        ; add to 16-bit digit of fptemp2
  151.     inc    di        ; point to next 16-bit digit
  152.     inc    di
  153.     loop    fpin12
  154. ;
  155. ; normalize
  156.     lea    di,fptemp1    ; point to fptemp1
  157.     call    fptnorm        ; renormalize it
  158. ;
  159. fpin13:
  160. ;
  161. ; decrement decimal exponent if dec flag is on
  162.     cmp    deflag,0    ; check decimal flag
  163.     je    fpin14        ; skip if not set
  164.     dec    decexp        ; dec exponent if set
  165. ;
  166. fpin14:
  167. ; adjust for the decimal point
  168.     add    al,30h        ; restore ASCII
  169.     and    al,5Fh        ; upper or lower case
  170.     cmp    al,'E'        ; is it E for Exponent ?
  171.     jne    fpin16
  172. ;
  173. ; grab exponent
  174. ;
  175.     call    sgnd16in    ; get signed decimal exponent
  176.     add    dexexp,dx    ; add it to our current value
  177. ;
  178. fpin16:
  179. ; check for sign of decimal exponent
  180.     mov    cx,decexp    ; get decimal exponent
  181.     cmp    cx,0        ; check its sign
  182.     jg    fpin17        ; if positive
  183.     jl    fpin18        ; if negative
  184. ;
  185. ; zero count
  186.     jmp    fpin20        ; done if exponent is zero
  187. ;
  188. ; positive decimal exponent
  189. fpin17:
  190.     push    cx        ; save count = decimal exponent
  191. ;
  192. ; multiply result by 10
  193.     lea    di,fptemp1    ; point to fptemp1
  194.     call    fptmul        ; multiply by 10
  195. ;
  196. ; normalize
  197.     lea    di,fptemp1    ; point to fptemp1
  198.     call    fptnorm        ; renormalize it
  199. ;
  200.     pop    cx        ; restore the count
  201.     loop    fpin17
  202. ;
  203.     jmp    fpin20        ; end of this case
  204. ;
  205. fpin18:
  206. ; negative count
  207.     neg    cx        ; absolute value of exponent
  208. fpin19:
  209.     push    cx        ; save count
  210. ;
  211. ; divide mantissa by 10
  212.     lea    di,fptemp1    ; point to fptemp1
  213.     call    fptdiv        ; divide by 10
  214. ;
  215. ; normalize
  216.     lea    di,fptemp1    ; point to fptemp1
  217.     call    fptnorm        ; renormalize it
  218. ;
  219.     pop    cx        ; restore count
  220.     loop    fpin19
  221. ;
  222. fpin20:
  223.     call    tfp2sfp        ; convert to single precision
  224. ;
  225.     pop    ax        ; restore registers
  226.     pop    cx
  227.     pop    dx
  228.     pop    si
  229.     pop    di
  230.  
  231. ;
  232.     ret            ; return
  233. ;
  234. fpin    endp
  235. ;-------------------------fpin ends---------------------------+
  236.